package com.mzj.saas.filter;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * token鉴权
 *
 * @author shun
 * @createDate: 2020年12月15日 上午11:17:34
 * @version: 1.0
 *
 */
public class AuthFilter extends OncePerRequestFilter {
	private static Logger LOG = LoggerFactory.getLogger(TokenUtil.class);
	@Value("${is.token.auth}")
	private boolean isTokenAuth;
	@Value("${no.authority.urls}")
	private String noAuthorityUrls;
	@Autowired
	private TokenUtil tokenUtil;
	@Autowired
	private AsyncHandleLogFactory asyncHandleLogFactory;

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		LOG.debug("AuthFilter doFilterInternal isTokenAuth = {}", isTokenAuth);
		if (isTokenAuth) {
			if (isAuth(request, response)) {
				filterChain.doFilter(request, response);
			} else {
				response.setStatus(401);
				ServletOutputStream out = response.getOutputStream();
				OutputStreamWriter ow = new OutputStreamWriter(out, "UTF-8");
				ow.write("{\"msg\":\"accessToken失效\",\"code\":\"401\"}");
				ow.flush();
				ow.close();
			}
		} else {
			filterChain.doFilter(request, response);
		}
	}

	public boolean isAuth(HttpServletRequest request, HttpServletResponse response) throws IOException {
		boolean flag = false;
		// String accessToken = request.getParameter("accessToken");
		String accessToken = request.getHeader("accessToken");// 对外服务token
		String requestManagerAuthToken = request.getHeader("manager-auth-header-token");// 后管的header
																						// token
		String URLPath = request.getRequestURI();// 请求路径
		LOG.debug("AuthFilter isAuth accessToken = {}, requestManagerAuthToken = {},URLPath = {}", accessToken,
				requestManagerAuthToken, URLPath);

		boolean managerFlag = false;// 后管系统token验证开关
		boolean externalFlag = false;// 对外接口token验证开关
		if (StringUtils.isNotBlank(URLPath) && !noAuthorityUrls.trim().contains(URLPath)) {

			// zhiping: restful 风格的要在这里加
			// 以后优化为带*的截取出来放这里判断
			if (URLPath.startsWith("/api/oss/file") || URLPath.startsWith("/api/sms/code/")
					|| URLPath.startsWith("/api/qiyuesuo/contract") || URLPath.startsWith("/api/aio")
					|| URLPath.startsWith("/api/index/apartment/recommend")
					|| URLPath.startsWith("/api/area/picker")
					|| URLPath.startsWith("/api/base")
					|| URLPath.startsWith("/api/hot/attractions/comboList")
					|| URLPath.startsWith("/api/biz/apartment")
					|| URLPath.startsWith("/api/biz/order")
					|| URLPath.startsWith("/api/rent/wxPay")
					|| URLPath.startsWith("/api/smart/lock/list")
					|| URLPath.startsWith("/api/electronicVisa/tencent/callback")
					|| URLPath.startsWith("/api/electronicVisa/fadada/callback")
					|| URLPath.startsWith("/api/front")
					|| URLPath.startsWith("/api/login/gainOpenId")
					|| URLPath.startsWith("/api/subscribe/serial")
					|| URLPath.startsWith("/api/houseBanner/user/list")
					|| URLPath.startsWith("/api/notice/user/list")
					|| URLPath.startsWith("/api/hidden")
					|| URLPath.startsWith("/api/captchaImage")
			) {
				return true;
			}

			if (StringUtils.isNotBlank(requestManagerAuthToken)) {
				managerFlag = tokenUtil.managerCheck(requestManagerAuthToken);
			}

			if (!managerFlag && StringUtils.isNotBlank(accessToken)) {
				externalFlag = tokenUtil.externalTokenCheck(accessToken);
			}

			if (managerFlag || externalFlag) {
				flag = true;
			} else {
				flag = false;
			}

		} else {
			flag = true;
		}

		// 记录操作日志
		HttpServletRequest req = (HttpServletRequest) request;
		try {
			operationLog(accessToken, req);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}
		LOG.debug("uthFilter isAuth flag = {}", flag);
		return flag;
	}

	/**
	 * 记录操作日志
	 *
	 * @author shun
	 * @date 2021年6月4日
	 */
	public void operationLog(String accessToken, HttpServletRequest req) {
		String method = req.getMethod();
		String path = req.getServletPath();

		String requestParam = null;
		if (method.equals(HttpGet.METHOD_NAME) || method.equals(HttpDelete.METHOD_NAME)) {
			requestParam = req.getQueryString();
		} else if (method.equals(HttpPost.METHOD_NAME) || method.equals(HttpPatch.METHOD_NAME)
				|| method.equals(HttpPut.METHOD_NAME)) {
			RequestWrapper requestWrapper;
			if (req instanceof RequestWrapper) {
				requestWrapper = (RequestWrapper) req;
				requestParam = requestWrapper.getBody();
			}
		}
		asyncHandleLogFactory.recordOper(accessToken, path, requestParam, method);
	}

}
